package f;

import java.io.Console;
import java.io.File;
import java.util.Calendar;
import java.util.Map;

import f.v4.PK;
import v4.file.FileDigest;
import v4.file.FileJm;
import v4.file.FileJmConfig;
import v4.text.FileTxtKit;
import v4.text.TextJm;
import v4.ui.ClipboardUtil;

public class FileOp implements Op {
	
	private File today;
	private String second;
	public void setAdd(int year, int week, String second) {
		if(second!=null) {
			this.second = second;
		}
		if(year>2000 && year<2999 && week>0 && week<=53) {
			File today = new File(Root.theRoot(), year+""+week);
			if(this.second!=null) {
				if(!today.exists() || !today.isDirectory()) {
					today.mkdir();
				}
				this.today = new File(today, second);
			}else {
				this.today = today;
			}
		}
	}
	
	@Override
	public int add(File old) {
		if(!old.exists() || old.isDirectory()) {
			return -1;
		}
		String f_hash = FileDigest.sha1(old);
		Map<String, Object> map = Db.defaultDb().select_f_hash(f_hash);
		if(map!=null) {
			return -1;
		}
		
		if(this.today == null) {
			Calendar cal = Calendar.getInstance();
			int year = cal.get(Calendar.YEAR);
			int week = cal.get(Calendar.WEEK_OF_YEAR);
			File today = new File(Root.theRoot(), year+""+week);
			if(this.second!=null) {
				if(!today.exists() || !today.isDirectory()) {
					today.mkdir();
				}
				this.today = new File(today, second);
			}else {
				this.today = today;
			}
		}
		if(!this.today.exists() || !this.today.isDirectory()) {
			this.today.mkdir();
		}
		
		int ret = 0;
		String f_type = FileExt.getType(old);
		if(FileExt.T3.equals(f_type)) {
			Vjpg vjpg = new Vjpg(old);
			try {
				vjpg.createJpg();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			int size = vjpg.rgSize();
			for(int i=1; i<=size; i++) {
				File old_n = new File(old.getParentFile(), Vjpg.getJpgName(old, i));
				if(old_n.exists()) {
					boolean ok = new Kit(old_n, new File(today, f_hash+"-"+(i)), jmConfig).startJm(key);
					if(ok) {
						ret++;
					}
				}
			}
		}
		
		boolean ok = new Kit(old, new File(today, f_hash), jmConfig).startJm(key);
		if(ok) {
			ret++;
		}
		return ret;
	}

	@Override
	public int delete(File jm) {
		if(!jm.exists()) {
			return -1;
		}
		String f_path = Root.getFPath(jm);
		if(f_path!=null) {
			if(jm.isDirectory()) {
				if(!f_path.endsWith("/")) {
					f_path = f_path + "/";
				}
				int ret = Db.defaultDb().deleteLike(f_path);
				File[] fs = jm.listFiles();
				boolean empty = true;
				for(File f: fs) {
					if(f.isDirectory()) {
						empty = false;
					}else {						
						f.delete();
					}
				}
				if(empty) {					
					jm.delete();
				}
				return ret;
			}else {
				int ret = Db.defaultDb().deleteLike(f_path);
				File[] fs = jm.getParentFile().listFiles();
				String name = jm.getName();
				int i = name.indexOf("-");
				//if(i!=-1) {
				if(i>0) {
					name = name.substring(0, i);
				}
				for(File f: fs) {
					if(f.isFile() && f.getName().startsWith(name)) {
						f.delete();
					}
				}
				return ret;
			}
		}
		return -1;
	}

	@Override
	public boolean backOne(File jmf, File to) {
		if(jmf.exists() && jmf.isFile()) {
			String f_path = Root.getFPath(jmf);
			if(f_path==null) {
				return false;
			}
			Map<String, Object> map = Db.defaultDb().select_f_path(f_path);
			//String t_hash = FileDigest.sha1(jmf);
			//Map<String, Object> map = Db.defaultDb().select_t_hash(t_hash);
			if(map==null) {
				return false;
			}
			String etext = (String)map.get("F_KEY");
			String f_ext = (String)map.get("F_EXT");
			File tof = null;
			if(to.isDirectory()) {
				tof = new File(to, jmf.getName()+"."+f_ext);
			}else if(to.getName().endsWith(f_ext)) {
				tof = to;
			}else {
				tof = new File(to.getParentFile(), to.getName()+"."+f_ext);
			}
			FileJm jm = new FileJm(jmf, tof, jmConfig);
			jm.decrypt(etext, key);
			return true;
		}
		return false;
	}
	
	public FileOp() {
		this.init();
	}
	
	private FileJmConfig jmConfig;
	private String key;
	void init() {
		String rootPath = pleaseInput("根目录: ");
		boolean inited = Root.initTheRoot(rootPath);
		if(inited) {
			msgln("根目录设置完成.");
			jmConfig = new FileJmConfig();
			File config = Root.theConfigFile();
			if(config.exists() && config.isFile()) {
				jmConfig.config(FileJmConfig.loadConfig(config));
				msgln("配置文件加载完成.");
			}else {
				msgln("使用默认配置.");
			}
			this.key = passwordInput();
			msgln("准备加载hardpassword.");
			File hdFile = Root.theHdFile();
			String hardpassword = null;
			if(hdFile.exists()) {
				String hdstr = FileTxtKit.getTxtKey(hdFile);
				TextJm tjm = new TextJm(jmConfig);
				hardpassword = tjm.decrypt(hdstr, key);
			}else {
				boolean createHardpassword = inputYesOrNo("是否生成hardpassword?");
				if(createHardpassword) {
					String hd = FileJmConfig.createHardpassword(4);
					ClipboardUtil.setSysClipboardText(hd);
					msgln("已复制到剪切板.");
					boolean saveHardpassword = inputYesOrNo("是否保存hardpassword?");
					if(saveHardpassword) {
						TextJm tjm = new TextJm(jmConfig);
						String hdstr = tjm.encryptAndCheck(hd, key);
						if(hdstr!=null) {
							boolean sv = FileTxtKit.saveText(hdFile, hdstr, false);
							if(sv) {
								msgln("保存hardpassword完成.");
							}
						}
					}
				}
				System.exit(0);
			}
			
			jmConfig.initHardpasswordMap(hardpassword);
			msgln("加载hardpassword完成.");
			PK.loadPK(jmConfig);
			msgln("加载PK完成.");
		}else {
			System.exit(0);
		}
	}
	
	public static String pleaseInput(String msg) {
		if(msg!=null) {
			System.out.println("[please input] "+msg);
		}
		Console c = System.console();
		String read = new String(c.readLine());
		return read;
	}
	public static boolean inputYesOrNo(String msg) {
		if(msg!=null) {
			msg(msg);
		}
		System.out.println("? yes or no. (y/n)?");
		Console c = System.console();
		String read = new String(c.readLine());
		if("y".equals(read) || "yes".equals(read)) {
			return true;
		}
		return false;
	}
	public static void msg(String msg) {
		System.out.print("[msg] "+msg);
	}
	public static void msgln(String msg) {
		System.out.println("[msg] "+msg);
	}
	
	public static String passwordInput() {
    	System.out.print("[key][please input]: ");
    	Console c = System.console();
    	return new String(c.readPassword());
    }

}
